# fexl language lexer+parser to use with packcc parser generator
%prefix "fexl"

%source{

#include <stdio.h>

static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };

#define PCC_DEBUG(event, rule, level, pos, buffer, length) \
    fprintf(stdout, "%*s%s %s @%d [%.*s]\n", (int)(level * 2), "", dbg_str[event], rule, (int)pos, (int)length,  buffer); fflush(stdout)

    /* NOTE: To guarantee the output order, stderr, which can lead a race condition with stdout, is not used. */

}

Fexl <- ws Expression+ Input? !.

Input <- '\\\\' .*

Expression <- Comment / ';' ws Expression* / Definition / Argument / Term

Comment <- '#' (![\n\r] .)* ws

Definition <- '\\' Symbol '=' ws Term / Recursive

Recursive <- '\\' Symbol '==' ws Term

Argument <- '\\' Symbol

Term <- open Expression+ close / Symbol

Symbol <- (String / (![ \t\n\r\\()"~;=] .)+) ws

String <- '"' (!'"' .)* '"' / Complex

Complex <- tilde '@' (!'@' .)* '@'

tilde <- '~'

open <- '(' ws

close <- ')' ws

ws <- [ \t\n\r]*


%%

int main() {
    fexl_context_t *ctx = fexl_create(NULL);
    while (fexl_parse(ctx, NULL)){;}
    fexl_destroy(ctx);
    return 0;
}

